package com.vcc.msc.sbs.proxy;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URLEncoder;
import java.util.ArrayList;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;

import android.util.Log;

import com.vcc.msc.sbs.common.Constants;
import com.vcc.msc.sbs.common.RequestMethodType;

public abstract class RESTClientProxyService implements Constants {
	protected ArrayList<NameValuePair> params;
	protected ArrayList<NameValuePair> headers;
	protected int statusCode;
	protected String errorMessage;

	public String execute(String methodName, RequestMethodType methodType)
			throws Exception {
		String xml = null;

		if (methodType.equals(RequestMethodType.GET)) {

			// add parameters
			String combinedParams = "";
			if (!params.isEmpty()) {
				combinedParams += "?";
				for (NameValuePair p : params) {
					String paramString = p.getName() + "="
							+ URLEncoder.encode(p.getValue(), "UTF-8");
					if (combinedParams.length() > 1) {
						combinedParams += "&" + paramString;
					} else {
						combinedParams += paramString;
					}
				}
			}

			String getUrl = WEBSERVICE_URL + methodName + combinedParams;
			HttpGet request = new HttpGet(getUrl);
			Log.d(RESTClientProxyService.class.toString(), getUrl);

			// add headers
			for (NameValuePair h : headers) {
				request.addHeader(h.getName(), h.getValue());
			}
			xml = callWebService(request);

		} else if (methodType.equals(RequestMethodType.POST)) {// TODO
			HttpPost request = new HttpPost(WEBSERVICE_URL);

			// add headers
			for (NameValuePair h : headers) {
				request.addHeader(h.getName(), h.getValue());
			}

			if (!params.isEmpty()) {
				request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
			}
			xml = callWebService(request);
		}
		cleanup();
		return xml;
	}

	private String callWebService(HttpUriRequest request) {

		HttpClient httpclient = new DefaultHttpClient();
		String xml = null;

		try {
			HttpResponse response = httpclient.execute(request);

			StatusLine statusLine = response.getStatusLine();
			statusCode = statusLine.getStatusCode();
			errorMessage = statusLine.getReasonPhrase();

			if (statusCode == REST_RESPONSE_OK) {
				HttpEntity entity = response.getEntity();
				InputStream instream = entity.getContent();

				xml = convertStreamToString(instream);
				Log.d(RESTClientProxyService.class.toString(), xml);

				// Closing the input stream will trigger connection release
				instream.close();
			} else {
				Log.e(RESTClientProxyService.class.toString(),
						"Failed to download file");
				// TODO exception handling
			}
			Log.d(this.getClass().getName(), "After Connection");
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return xml;
	}

	private String convertStreamToString(InputStream instream)
			throws IOException {
		StringBuilder builder = new StringBuilder();
		String xml;
		BufferedReader reader = new BufferedReader(new InputStreamReader(
				instream));
		String line;
		while ((line = reader.readLine()) != null) {
			builder.append(line);
		}
		xml = builder.toString();
		return xml;
	}

	public void addParam(String name, String value) {
		if (params == null) {
			params = new ArrayList<NameValuePair>();
		}
		params.add(new BasicNameValuePair(name, value));
	}

	public void addHeader(String name, String value) {
		if (headers == null) {
			headers = new ArrayList<NameValuePair>();
		}
		headers.add(new BasicNameValuePair(name, value));
	}

	public int getStatusCode() {
		return statusCode;
	}

	public String getErrorMessage() {
		return errorMessage;
	}

	public void cleanup() {
		statusCode = 0;
		errorMessage = null;
		headers = null;
		params = null;
	}
	// public void writeJSON() {
	// JSONObject object = new JSONObject();
	// try {
	// object.put("name", "Jack Hack");
	// object.put("score", new Integer(200));
	// object.put("current", new Double(152.32));
	// object.put("nickname", "Hacker");
	// } catch (JSONException e) {
	// e.printStackTrace();
	// }
	// System.out.println(object);
	//
	// String xml =
	// "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><infoBean><description>Yes it worked!</description><id>parameter</id><summary>test info</summary></infoBean>";
	// Info infoBean = convertXMLToObject(xml);
	// System.out.println(infoBean.toString());
	// }

}
